Skip to content

feat(notifications): real-time WebSocket invoice event notifications (#9) - #1

Open
Mhidesav wants to merge 23 commits into
feat/invoice-state-machinefrom
feat/ws-invoice-notifications
Open

feat(notifications): real-time WebSocket invoice event notifications (#9)#1
Mhidesav wants to merge 23 commits into
feat/invoice-state-machinefrom
feat/ws-invoice-notifications

Conversation

@Mhidesav

Copy link
Copy Markdown
Owner

Summary

Closes Nova-reward#9

Implements real-time notifications for invoice lifecycle events via WebSocket (Socket.IO).

Changes

Backend (NestJS)

  • NotificationsGateway — WebSocket gateway broadcasting invoice_event to all clients; accepts publish_invoice_event from clients
  • NotificationsModule — wires the gateway
  • InvoiceEvent DTO — typed interface (created | submitted | funded | repaid | defaulted)

Frontend (React)

  • useInvoiceNotifications hook — connects via Socket.IO, tracks connection state, returns events most-recent-first

CI

  • .github/workflows/app-ci.yml — runs backend + frontend Jest tests on push/PR to backend/** or frontend/**

Tests

Suite Tests Status
Backend (NestJS/Jest) 4 ✅ pass
Frontend (Jest/jsdom) 5 ✅ pass

InvoiceFi Bot and others added 23 commits June 21, 2026 09:13
…ons (Nova-reward#9)

- Add NestJS WebSocket gateway (NotificationsGateway) that broadcasts
  invoice lifecycle events (created, submitted, funded, repaid, defaulted)
  to all connected Socket.IO clients
- Add NotificationsModule wiring gateway into AppModule
- Add InvoiceEvent DTO with typed event names
- Add 4 backend unit tests (Jest) covering broadcast and publish flows
- Add React useInvoiceNotifications hook (socket.io-client) that
  subscribes to invoice_event and tracks connection state
- Add 5 frontend unit tests covering connect, event accumulation,
  ordering, and cleanup
- Add GitHub Actions app-ci.yml workflow running backend and frontend
  tests on changes to backend/** or frontend/**
…unit test suite

The core Soroban contracts had no automated tests because the contracts
themselves did not yet exist in the repo. This adds a Cargo workspace under
contracts/ with the two contracts under test and a comprehensive unit-test
suite using soroban_sdk::testutils.

invoice contract:
- mint (auth + zero/negative-value rejection, monotonic ids)
- transfer (ownership, non-owner / self-transfer / missing-invoice guards)
- update_status lifecycle state machine (Pending/Funded/Settled/Defaulted)
- metadata retrieval views (get_invoice, owner_of, status_of, exists)

financing-pool contract:
- deposit / withdraw with auth and balance/liquidity guards
- fund_invoice with discounted advance
- discount calculation (quote / discount_amount, basis points, floor rounding)

Edge cases covered: zero-value funding, duplicate invoice ids, unauthorized
callers, illegal state transitions, insufficient liquidity/balance.

CI: .github/workflows/contracts.yml runs cargo fmt --check, clippy -D warnings,
and cargo test on every push and PR. All 45 tests pass locally.

Closes Nova-reward#11
Funded invoices become transferable on-chain ownership tokens representing the
repayment claim. Invoices are non-fungible, so the interface is NFT-flavored
(one unique token per invoice) using SEP-0041 naming and the approve /
transfer_from delegation pattern.

- fund(invoice_id, discount_rate): canonical Pending -> Funded transition that
  mints the invoice's unique token and snapshots its metadata (invoice id, face
  value, discount rate, due date). Replaces the update_status funding path.
- get_invoice_token / get_invoice_token_owner / is_tokenized query functions.
- approve / get_approved / transfer_from for delegated transfers; approval is
  consumed on transfer and cleared on any direct transfer.
- transfer is blocked once an invoice is repayment-settled.

Tests: +19 invoice tests (token mint/metadata, ownership queries, transfer
rules incl. post-repayment block, approve/transfer_from, auth). Existing
lifecycle tests migrated to the fund() path. 64 tests pass; fmt + clippy clean.

Note: the "frontend displays token ownership" criterion is not addressed here
because the repo has no frontend application yet (frontend/ contains only a
Dockerfile). The get_invoice_token_owner / get_invoice_token views expose
exactly what an invoice detail page needs to consume.

Closes Nova-reward#8
Funded invoices stayed FUNDED after the settlement contract repaid them
on-chain because there was no backend listener for the InvoiceSettled event.
This adds the NestJS + Prisma backend (the repo previously had only a
Dockerfile) with a Soroban settlement listener.

- soroban-events.service: polls Soroban RPC getEvents and decodes XDR
  topics/value into native values.
- settlement-event.parser: pure parser recognizing InvoiceSettled events and
  extracting the invoice id.
- settlement.service: FUNDED -> REPAID via a conditional updateMany in a
  transaction — atomic and idempotent (replayed events are a no-op).
- settlement-sync.service: polls every 5s (dashboards reflect within ~10s),
  settles each event through withRetry (max 3 attempts, exponential backoff),
  and only advances the ledger cursor past fully-processed ledgers so a failing
  event is retried next cycle instead of being skipped.
- invoices/dashboard REST endpoints + /health so dashboards read fresh status.
- Prisma schema (Invoice, SyncCursor) + initial migration.

Tests: 21 unit tests (retry backoff, event parsing, atomic/idempotent
settlement, cursor advancement + retry/resume), all mocked so they run with no
DB or chain. npm test and npm run build pass.

Closes Nova-reward#3
… nonce replay protection

Adds a new contracts/ workspace containing three Soroban (Rust) smart contracts
for the InvoiceFi Stellar protocol: invoice, financing-pool, and settlement.

Security hardening:
- Every mutating entry point calls env.require_auth(&caller) before any business logic.
- settlement.settle_invoice accepts a nonce: u64 parameter; used nonces are persisted
  in contract storage and rejected on reuse, preventing replay attacks.
- Nonce entries expire after invoice due_date + 30 days (2592000 s) to bound storage growth.
- get_used_nonces read function exposed for on-chain auditability.
- contracts/SECURITY.md documents the full authorization model, role hierarchy,
  nonce mechanism, event observability, and audit checklist.
test: implement invoice lifecycle e2e tests
…tract-test-suite

test(contracts): Soroban invoice & financing-pool contracts with unit test suite
…-tokenization

feat(invoice): SEP-0041-style NFT tokenization of funded invoices
…tatus-sync

fix(backend): sync invoice status to REPAID on on-chain settlement
…o-table

Add investor portfolio dashboard scaffold with sorting, filtering, pa…
feat(contracts): add Soroban smart contracts with systematic auth and…
Redesign invoice creation flow with multi-step wizard
feat: implement investor pool metrics dashboard
feat: implement role-based access control for frontend and backend
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants